import { ref } from "vue";
import { DataGridColumn, DataGridProps } from "../data-grid.props";
import { UseDataRow, UseEdit, UseVisualDataBound, UseVisualDataCell, VisualData, VisualDataStatus, VisualDataType } from "./types";

export function useVisualDataRow(
    props: DataGridProps,
    useEditComposition: UseEdit,
    useVisualDataBoundComposition: UseVisualDataBound,
    useVisualDataCell: UseVisualDataCell
): UseDataRow {
    const rowOption = ref(props.rowOption);
    const rowHeight = rowOption.value?.height || 28;
    const autoRowHeight = rowOption.value?.wrapContent || false;
    const identifyField = ref(props.idField);
    const { updateRowPosition } = useVisualDataBoundComposition;
    const { createCellByColumn } = useVisualDataCell;

    function createEmptyRow(type: VisualDataType, index: number, dataItem: any, pre: any, top: number) {
        const {
            __fv_data_grid_group_collapse__: collapse,
            __fv_data_grid_group_field__: groupField,
            __fv_data_grid_group_value__: groupValue,
            __fv_data_index__: dataIndex,
            __fv_data_grid_group_layer__: layer
        } = dataItem;

        const currentRow: VisualData = {
            collapse, data: {}, dataIndex, groupField, groupValue, layer,
            index, pre, top, type, setRef: (vnode) => { currentRow.ref = vnode; },
            status: VisualDataStatus.initial
        };
        if (!autoRowHeight) {
            currentRow.height = rowHeight;
            dataItem.__fv_data_height__ = currentRow.height;
            updateRowPosition(currentRow, dataItem);
        }
        return currentRow;
    }

    // eslint-disable-next-line max-len
    function createNewRowFromDataItem(columns: DataGridColumn[], dataItem: any, preDataItem: any, preRow: VisualData, rowIndex: number, top: number) {
        const currentRow = createEmptyRow(VisualDataType.data, rowIndex, dataItem, preDataItem, top);
        columns.forEach((column: DataGridColumn, columnIndex: number) => {
            currentRow.data[column.field] = createCellByColumn(column, columnIndex, dataItem, currentRow, preRow);
        });
        return currentRow;
    }

    function restoreFromSnapshot(editingSnapshot: VisualData, index: number, dataIndex: number, top: number, pre: VisualData) {
        const currentRow = Object.assign(editingSnapshot, { index, dataIndex, top, pre });
        return currentRow;
    }

    function renderDataRow(
        dataItem: any,
        preDataItem: any,
        preRow: VisualData,
        rowIndex: number,
        top: number,
        columns: DataGridColumn[]
    ): VisualData {
        const dataIndex = dataItem.__fv_data_index__;
        const dataIdentify = dataItem[identifyField.value];
        const editingSnapshot = useEditComposition.getEditingSnapshot(dataIdentify) as VisualData;
        const shouldCreateNewRow = editingSnapshot === null;
        const currentRow = shouldCreateNewRow ? createNewRowFromDataItem(columns, dataItem, preDataItem, preRow, rowIndex, top) :
            restoreFromSnapshot(editingSnapshot, rowIndex, dataIndex, top, preRow);
        return currentRow;
    }

    return { createEmptyRow, createNewRowFromDataItem, renderDataRow };
}
